import time
import socket
from urllib import parse
from urllib.parse import SplitResult

from kazoo import exceptions
from kazoo.client import KazooClient


class RegistryProvider(object):
    def __init__(self, hosts, app_name, service_host, service_port) -> None:
        super().__init__()
        self._kazoo_client = KazooClient(hosts)
        self._kazoo_client.start()
        self._app_name = app_name
        self._service_host = service_host
        self._service_port = service_port
        self._provider_node = ProviderNode(service_host, service_port)

    @classmethod
    def listener(cls, stat):
        print(stat)

    def registry(self, interface, methods):
        node_path = self._provider_node.get_node_path(interface,
                                                      application=self._app_name,
                                                      anyhost='true',
                                                      dubbo='2.6.2',
                                                      generic='false',
                                                      pid=123456,
                                                      server='sanic-jsonrpc',
                                                      side='provider',
                                                      timestamp=int(time.time() * 1000),
                                                      methods=methods)
        try:
            self._kazoo_client.get(node_path)
            self._kazoo_client.set(node_path, bytes(self._service_host, encoding='utf-8'))
        except exceptions.NoNodeError:
            self._kazoo_client.create(node_path, bytes(self._service_host, encoding='utf-8'), ephemeral=True,
                                      makepath=True)
        self._kazoo_client.add_listener(self.listener)


class ProviderNode(object):
    def __init__(self, host, port) -> None:
        super().__init__()
        self._host = host
        self._port = port

    def get_url(self, interface, **kwargs):
        kwargs.update({'interface': interface})
        return parse.quote_plus(parse.urlunsplit(SplitResult(scheme='jsonrpc',
                                                             netloc="%s:%s" % (self._host, self._port),
                                                             path='/dubbo/' + interface,
                                                             query=parse.urlencode(kwargs),
                                                             fragment='')))

    def get_node_path(self, interface, **kwargs):
        return "/dubbo/" + interface + "/providers/" + self.get_url(interface, **kwargs)


def provider_address(zoo_address):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    items = zoo_address.split(":")
    s.connect((items[0], int(items[1])))
    address = s.getsockname()[0]
    s.close()
    return address
